﻿using System.Collections;
using UnityEngine;

using ScFramework.Core;
using System.Collections.Generic;
using System;

public class PhysicsClient : LogicModuleBase<MessageManager,UserManager>,IPhysicsClient
{
    List<EntityChangeArgs> _messageQueue;
    List<EntityChangeArgs> _receivedMessages;
    List<EntityChangeArgs> _localChangeQueue;
    public override void OnInit(object args = null)
    {
        base.OnInit(args);
        _messageQueue = new List<EntityChangeArgs>();
        _receivedMessages = new List<EntityChangeArgs>();
        _localChangeQueue = new List<EntityChangeArgs>();
        SysModule.Get<LocalServerEntityDataEvent>().RegisterHandler(LocalServerEntityDataEvent.ToPhysics, Receive);
    }

    #region listen
    [RegisterEvent(EntityDataEvent.Created)]
    void SetListenToLocalEntityCreate(EntityData data)
    {
        _localChangeQueue.Add(new EntityChangeArgs(new EntityCreatedArgs(data)));
    }
    [RegisterEvent(EntityDataEvent.Deleted)]
    void SetListenToLocalEntityDelete(UInt16 id)
    {
       _localChangeQueue.Add(new EntityChangeArgs(new EntityDeleteArgs(id)));
    }
    [RegisterEvent(EntityDataEvent.ValueChanged)]
    void SetListenToLocalValueChange(ValueChangeArgs args)
    {
        _localChangeQueue.Add(new EntityChangeArgs(args));

        if(args.ValueID.right()==2)
        Debug.Log(args.Value);
    }

    [RegisterEvent(EntityDataReq.Create)]
    void SetListenToEntityCreate(UInt32 id) 
    {
            _messageQueue.Add(new EntityChangeArgs(new EntityCreateArgs(id)));
    }
    [RegisterEvent(EntityDataReq.Delete)]
    void SetListenToEntityDelete(UInt16 id)
    {
            _messageQueue.Add(new EntityChangeArgs(new EntityDeleteArgs(id)));
    }
    [RegisterEvent(EntityDataReq.ValueChange)]
    void SetListenToValueChange(ValueChangeArgs args)
    {
            _messageQueue.Add(new EntityChangeArgs(args));
    }
#endregion



    public override void OnDestroy()
    {
        base.OnDestroy();


        _messageQueue.Clear();
        _receivedMessages.Clear();
        _localChangeQueue.Clear();
    }

    void Receive(List<EntityChangeArgs> messages)
    {
        _receivedMessages.AddRange(messages);
    }

    public void Send()
    {
        var ans = new List<EntityChangeArgs>(_messageQueue);
        _messageQueue.Clear();
        SysModule.Get<LocalServerEntityDataEvent>().DispatchMessage(LocalServerEntityDataEvent.FromPhysics, this, new EntityDataReqArgs
        {
            messages = ans
        });
        ans = new List<EntityChangeArgs>(_localChangeQueue);
        _localChangeQueue.Clear();
        SysModule.Get<LocalServerEntityDataEvent>().DispatchMessage(LocalServerEntityDataEvent.FromPhysics, this, new EntityDataLocalArgs
        {
            messages = ans
        });
    }


    EventArgs Receive(object sender, EventArgs e)
    {
        if (e is EntityDataReqArgs ee)
        {
            if (ee.messages != null)
            {
         //       Dispatch(PhysicsProcessEvent.SetCamerePos, new Tuple<Vector3, Vector3>(ee.CameraPositon,ee.CameraViewSiz));
               Receive(ee.messages);
            }
        }
        return null;

    }


    public void SolveMessage()
    {
        ///先执行创建和销毁,再进行属性同步
        var messages = _receivedMessages.FindAll(s => s.ChangeType==EntityChangeType.Create || s.ChangeType == EntityChangeType.Delete||s.ChangeType==EntityChangeType.CreateWithAction);

        foreach(var x in messages)
        {
            if (x.ChangeType == EntityChangeType.Create)
            {
                if (SysModule1.IsHost)
                {
                    Debug.Assert((x.Args as EntityCreateArgs).EntityID.right() == 0);
                    Dispatch(EntityDataEvent.Create, (x.Args as EntityCreateArgs).EntityID.left());
                }
                else
                {
                    Debug.Assert((x.Args as EntityCreateArgs).EntityID.right() != 0);
                    Dispatch(EntityDataEvent.Create,(x.Args as EntityCreateArgs).EntityID);
                }
            }else if (x.ChangeType == EntityChangeType.CreateWithAction)
            {
                Debug.Assert(SysModule1.IsHost);
                Dispatch(EntityDataEvent.Create, (x.Args as EntityCreateWithActionArgs).Args);
            }
            else if(x.ChangeType==EntityChangeType.Delete)
            {
                Dispatch(EntityDataEvent.Delete,(x.Args as EntityDeleteArgs).EntityID);
            }
            else
            {
                throw new Exception()
;            }
        }
        messages = _receivedMessages.FindAll(s => s.ChangeType == EntityChangeType.ValueChange);
        _receivedMessages.Clear();
        Dispatch(PhysicsProcessEvent.EntityData_SelectInstance);
        foreach(var x in messages)
        {
            Dispatch(EntityDataEvent.ValueChange, x.Args);
        }
    }
}
public interface IPhysicsClient
{
//    void Receive(List<PhysicsMessage> messages);
    void Send();

    void SolveMessage();
}

